package com.ziyueyuwen.xiniao.controller.report;

import com.alibaba.fastjson.JSONObject;
import com.suyeer.basic.util.HttpResUtil;
import com.suyeer.basic.util.LogUtil;
import com.ziyueyuwen.xiniao.base.HttpResContent;
import com.ziyueyuwen.xiniao.bean.ZyClassLessonInfo;
import com.ziyueyuwen.xiniao.bean.ZyClassLessonTransfer;
import com.ziyueyuwen.xiniao.bean.ZyClassLessonUser;
import com.ziyueyuwen.xiniao.bean.ZyUser;
import com.ziyueyuwen.xiniao.bean.homework.*;
import com.ziyueyuwen.xiniao.bean.report.ReportUpdateVO;
import com.ziyueyuwen.xiniao.bean.report.StudentLessonReportVO;
import com.ziyueyuwen.xiniao.bean.report.StudentReportForTeacherWriteVO;
import com.ziyueyuwen.xiniao.bean.report.ZyStudentLessonReport;
import com.ziyueyuwen.xiniao.bean.vo.ZyClassLessonUserVO;
import com.ziyueyuwen.xiniao.bean.vo.ZyClassUserVO;
import com.ziyueyuwen.xiniao.bean.vo.ZyLessonVO;
import com.ziyueyuwen.xiniao.controller.lesson.LessonController;
import com.ziyueyuwen.xiniao.enums.HomeworkStatusEnum;
import com.ziyueyuwen.xiniao.enums.ParamTypeEnum;
import com.ziyueyuwen.xiniao.enums.ReportInOutEnum;
import com.ziyueyuwen.xiniao.service.*;
import com.ziyueyuwen.xiniao.service.baseservice.lesson.ZyClassLessonService;
import com.ziyueyuwen.xiniao.service.report.ReportService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.ziyueyuwen.xiniao.base.BaseUtil.checkParam;
import static com.ziyueyuwen.xiniao.base.BaseUtil.saveErrorMsgAndData;
import static com.ziyueyuwen.xiniao.base.BaseUtil.saveSuccessMsgAndData;
import static com.ziyueyuwen.xiniao.util.ConstUtil.*;

/**
 * Created by wancheng on 2019/3/26.
 */
@Validated
@Controller
@RequestMapping("/report")
public class ReportController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    LessonService lessonService;
    @Autowired
    UserService userService;
    @Autowired
    ZyClassLessonService zyClassLessonService;
    @Autowired
    MessageTaskTemplateService messageTaskTemplateService;
    @Autowired
    ReportService reportService;
    @Autowired
    SubjectQuestionService subjectQuestionService;
    @Autowired
    HomeworkRecordService homeworkRecordService;
    @Autowired
    LessonUserService lessonUserService;
    @Autowired
    ClassUserService classUserService;
    @Autowired
    TransferStudentService transferStudentService;
    @Autowired
    WxMessageService wxMessageService;

    @RequestMapping(value = "/get_lesson_students_report.do", method = RequestMethod.POST)
    public void getLessonStudentsReport(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Integer lessonId) {
        HttpResContent<Map<String, Object>> hrc = new HttpResContent<>(request, response);
        hrc.setFuncDes("获取课堂学生报告");
        try {
            checkParam(ParamTypeEnum.INTEGER_GT_0, "lessonId", lessonId);
            List<StudentLessonReportVO> res = reportService.getStudentLessonReport(lessonId);
            //ZyLessonVO lessonVO = lessonService.getClassAndCourseByLessonId(lessonId);
            Integer total = 0;
            try {
                /*ZySubjectQuestionDO subjectQuestionDO = subjectQuestionService.getBySubjectIdAndHomeworkIndex(lessonVO.getCourse().getSubjectId(), lessonVO.getLessonIndex());
                List<QuestionInfo> questionInfoList = subjectQuestionDO.getQuestionInfoList();
                List<TreeMap<String, Integer>> scoreMapList = questionInfoList.stream().map(QuestionInfo::getScoreMap).collect(Collectors.toList());

                for (TreeMap<String, Integer> t : scoreMapList) {
                    for (Map.Entry<String, Integer> e : t.entrySet()) {
                        total = total + e.getValue();
                    }
                }*/
                for (StudentLessonReportVO v : res) {
                    v.setUrl(wxMessageService.getReportUrl(lessonId,v.getStudentAccount()));
                    ZyHomeworkRecordDO homeworkRecordDO = homeworkRecordService.getByStudentIdAndLessonId(v.getStudentAccount(), v.getLessonId());
                    if (homeworkRecordDO != null) {
                        v.setHomeworkRecordId(homeworkRecordDO.getId());
                        for (AnswerData a : homeworkRecordDO.getAnswerInfoList()) {
                            total += a.getTotalScore();
                        }

                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                LogUtil.error(e);
            }
            Map<String, Object> map = new HashMap<>(2);
            map.put("reports", res);
            map.put("totalScore", total);
            saveSuccessMsgAndData(hrc, map);
        } catch (Exception e) {
            e.printStackTrace();
            saveErrorMsgAndData(hrc, e);
        } finally {
            HttpResUtil.writeResult(hrc, true);
        }
    }

    @RequestMapping(value = "/update_report_note_level.do", method = RequestMethod.POST)
    public void updateReportNoteAndLevel(@Validated ReportUpdateVO updateVO) {
        HttpResContent<Boolean> hrc = new HttpResContent<>("修改报告的课堂笔记或者等级");
        ZyStudentLessonReport report = new ZyStudentLessonReport();
        report.setId(updateVO.getId())
                .setIfHasNote(updateVO.getIfHasNote())
                .setLevel(updateVO.getLevel());
        if (updateVO.getScore() != null) {
            report.setScore(updateVO.getScore())
                    .setHomework(HomeworkStatusEnum.CORRECTED_MATERIAL);
        }
        reportService.updateByPreKey(report);
        hrc.printLogAndResponse(true);
    }

    @RequestMapping(value = "/get_student_report_details.do", method = RequestMethod.POST)
    public void getReportDetails(@RequestParam(PARAM_CLASS_ID) Integer classId,
                                 @RequestParam(PARAM_STUDENT_ACCOUNT) String studentAccount) {
        HttpResContent<List<ZyStudentLessonReport>> hrc = new HttpResContent<>("查看班级中学生报告详情");
        checkParam(ParamTypeEnum.INTEGER_GT_0, PARAM_CLASS_ID, classId);
        checkParam(ParamTypeEnum.STRING_NOT_BLANK, PARAM_STUDENT_ACCOUNT, studentAccount);
        ZyStudentLessonReport param = new ZyStudentLessonReport();
        param.setClassId(classId)
                .setStudentAccount(studentAccount);
        List<ZyStudentLessonReport> res = reportService.getReport(param);
        res = res.stream().sorted(((o1, o2) -> Integer.compare(o1.getLessonIndex(), o2.getLessonIndex()))).collect(Collectors.toList());
        hrc.printLogAndResponse(res);
    }

    @RequestMapping(value = "/report_msg_for_init.do", method = RequestMethod.POST)
    public void reportMsgForInit(@RequestParam(PARAM_LESSON_ID) Integer lessonId) {
        HttpResContent<JSONObject> hrc = new HttpResContent<>("老师填写课堂报告,获取学生在该课堂报告的相关数据");
        checkParam(ParamTypeEnum.INTEGER_GT_0, PARAM_LESSON_ID, lessonId);
        ZyLessonVO lesson = lessonService.getClassAndCourseByLessonId(lessonId);
        //班级内的学生
        List<ZyClassUserVO> classLessonUserVOs = classUserService.getStudent(lesson.getClassId());
        //转为map结构
        Map<String, ZyClassUserVO> classStudentMap = classLessonUserVOs.stream().collect(Collectors.toMap(ZyClassUserVO::getUserAccount, u -> u));
        //该课堂的报告
        List<StudentLessonReportVO> lessonStudentReport = reportService.produceLessonReport(lessonId);
        Boolean ifFinished = false;
        for (StudentLessonReportVO r : lessonStudentReport) {
            if (StringUtils.isNotBlank(r.getReport())) {
                ifFinished = true;
                break;
            }
        }
        if (ifFinished) {
            JSONObject res = new JSONObject();
            res.put("ifFinished", ifFinished);
            hrc.printLogAndResponse(res);
            return;
        }
        //转map结构
        Map<String, StudentLessonReportVO> lessonStudentReportMap = lessonStudentReport.stream().collect(Collectors.toMap(StudentLessonReportVO::getStudentAccount, p -> p));
        //调出生
        List<String> transferStudentName = lessonStudentReportMap.entrySet().stream().filter(e -> !classStudentMap.keySet().contains(e.getKey()))
                .map(e -> e.getValue().getStudentName()).collect(Collectors.toList());
        Map<ReportInOutEnum, List<StudentLessonReportVO>> attendanceMap = lessonStudentReport.stream()
                .filter(l->l.getAttendance() != null)
                .collect(Collectors.groupingBy(StudentLessonReportVO::getAttendance));
        //缺课学生姓名
        List<String> absentStudentName = new ArrayList<>();
        if (attendanceMap.get(ReportInOutEnum.ABSENT) != null) {
            absentStudentName = attendanceMap.get(ReportInOutEnum.ABSENT).stream().map(StudentLessonReportVO::getStudentName).collect(Collectors.toList());
        }
        //正常学生的课堂报告 包括准时 和迟到的学生
        List<StudentLessonReportVO> normalStudentReport = lessonStudentReport.stream().filter(p -> !ReportInOutEnum.ABSENT.equals(p.getAttendance())).collect(Collectors.toList());
        List<StudentReportForTeacherWriteVO> teacherWriteData = new ArrayList<>();
        for (StudentLessonReportVO rvo : normalStudentReport) {
            StudentReportForTeacherWriteVO write = new StudentReportForTeacherWriteVO();
            write.setLessonId(lessonId);
            write.setPreview(rvo.getPreview());
            write.setStudentAccount(rvo.getStudentAccount());
            write.setStudentName(rvo.getStudentName());
            write.setAward(rvo.getAward());
            write.setAttendance(rvo.getAttendance());
            ClassroomTestRecordDataDTO classroomTestRecordData = homeworkRecordService.getData4ClassroomTestReport(rvo.getStudentAccount(), lessonId);
            if (classroomTestRecordData != null) {
                write.setPerRate(classroomTestRecordData.getPerRate());
                write.setAverageRate(classroomTestRecordData.getTotalRate());
            }
            teacherWriteData.add(write);
        }

        JSONObject res = new JSONObject();
        res.put("lesson", lesson);
        res.put("transfer", transferStudentName);
        res.put("absent", absentStudentName);
        res.put("normal", teacherWriteData);
        hrc.printLogAndResponse(res);
    }

    @RequestMapping(value = "/lesson_report_save.do", method = RequestMethod.POST)
    public void reportUpdate(@RequestParam(PARAM_LESSON_ID) Integer lessonId,
                             @RequestParam(PARAM_STUDENT_ACCOUNT) String studentAccount,
                             @RequestParam(PARAM_REPORT) String report,
                             @RequestParam(PARAM_REPORT_CLASS_TEST_COUNT)Integer classTestCount,
                             @RequestParam(PARAM_REPORT_PER_RATE)String perRate,
                             @RequestParam(PARAM_REPORT_AVERAGE_RATE)String averageRate) {
        HttpResContent<Boolean> hrc = new HttpResContent<>("保存学生的课堂报告");
        checkParam(ParamTypeEnum.INTEGER_GT_0, PARAM_LESSON_ID, lessonId);
        checkParam(ParamTypeEnum.STRING_NOT_BLANK, PARAM_STUDENT_ACCOUNT, studentAccount);
        ZyStudentLessonReport lessonReport = reportService.getReportMsgWhileIsNUllToSave(studentAccount, lessonId);
        ZyStudentLessonReport update = new ZyStudentLessonReport();
        update.setId(lessonReport.getId());
        update.setReport(report);
        update.setClassTestCount(classTestCount);
        update.setPerRate(JSONObject.parseObject(perRate));
        update.setAverageRate(averageRate);
        reportService.updateByPreKey(update);
        reportService.sendMsgForStudentReport(lessonId, studentAccount);
        hrc.printLogAndResponse(true);
    }

    @RequestMapping(value = "/student_lesson_feedback.do", method = RequestMethod.POST)
    public void studentLessonReport(@RequestParam(PARAM_LESSON_ID) Integer lessonId,
                                    @RequestParam(PARAM_STUDENT_ACCOUNT) String studentAccount) {
        HttpResContent<JSONObject> hrc = new HttpResContent<>("学生查看课堂反馈报告");
        checkParam(ParamTypeEnum.INTEGER_GT_0, PARAM_LESSON_ID, lessonId);
        checkParam(ParamTypeEnum.STRING_NOT_BLANK, PARAM_STUDENT_ACCOUNT, studentAccount);
        JSONObject res = new JSONObject();
        ZyUser student = userService.getByAccount(studentAccount);
        ZyStudentLessonReport lessonReport = reportService.getReportMsgWhileIsNUllToSave(studentAccount, lessonId);
        if (lessonReport != null) {
            ZyStudentLessonReport before = new ZyStudentLessonReport();
            before.setStudentAccount(lessonReport.getStudentAccount());
            before.setClassId(lessonReport.getClassId());
            before.setLessonIndex(lessonReport.getLessonIndex() - 1);
            before = reportService.getOne(before);
            res.put("before", before);
            ZyClassLessonInfo lessonInfo = lessonService.getByPreKey(lessonReport.getLessonId());
            res.put("currentLessonBeginTime", lessonInfo.getBeginTime());
        }
        res.put("current", lessonReport);
        res.put("studentName", student.getUserName());
        hrc.printLogAndResponse(res);
    }
}
